/** @format */

import React from 'react';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableContainer from '@material-ui/core/TableContainer';
import TableHead from '@material-ui/core/TableHead';
import TablePagination from '@material-ui/core/TablePagination';
import TableRow from '@material-ui/core/TableRow';
import TableSortLabel from '@material-ui/core/TableSortLabel';
import Paper from '@material-ui/core/Paper';
import AlertDialog from '@/view/admin/component/dialog';
import {admin as adminApi} from '@/api/admin';
import Button from '@material-ui/core/Button';
import Edit from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
import Visibility from '@material-ui/icons/Visibility';
import {FragmentWrap} from './index.styl';
import Dialog from '@material-ui/core/Dialog';
import DialogTitle from '@material-ui/core/DialogTitle';
import DialogContent from '@material-ui/core/DialogContent';
import DialogActions from '@material-ui/core/DialogActions';
import Typography from '@material-ui/core/Typography';
import trans from '@/api';

// 提示框
interface IAlertDialog {
  open: boolean;
  // 默认 top
  vertical?: 'top' | 'bottom';
  // 默认 center
  horizontal?: 'left' | 'center' | 'right';
  // 默认 ''
  msg: string;
  // 默认 info
  severity?: 'error' | 'warning' | 'info' | 'success';
  // 多少秒后消失
  autoHideDuration?: number;
}

interface IProps {
  [propName: string]: any;
}

interface ITableHeadProps {
  numSelected: number;
  onRequestSort: (event: React.MouseEvent<unknown>, property: string) => void;
  order: string;
  orderBy: string;
  rowCount: number;
}

interface ITableHeadCell {
  disablePadding: boolean;
  id: string;
  label: string;
  numeric: boolean;
}

interface ITitle {
  title: string;
  align: 'left' | 'center' | 'right' | 'inherit' | 'justify' | undefined;
}

interface ITableHeadComponent {
  orderBy: number;
  order: 'asc' | 'desc' | undefined;
}

class TableHeadComponent extends React.Component<IProps, ITableHeadComponent> {
  constructor(props: IProps) {
    super(props);
    this.state = {orderBy: -1, order: undefined};
  }

  sortHandler(title: string, index: number) {
    const order = this.state.orderBy === index && this.state.order === 'asc' ? 'desc' : 'asc';
    this.setState({order, orderBy: index});
    this.props.onRequestSort(order, title);
  }

  render() {
    const titles: ITitle[] = [
      {title: 'id', align: 'left'},
      {title: 'Title', align: 'left'},
      {title: 'Category', align: 'left'},
      {title: 'Release Date', align: 'center'},
      {title: 'Visits', align: 'center'},
      {title: 'Operate', align: 'center'},
    ];

    return (
      <TableHead>
        <TableRow>
          {titles.map((headCell, index) => (
            <TableCell key={index} align={headCell.align}>
              <TableSortLabel
                active={this.state.orderBy === index}
                direction={this.state.orderBy === index ? this.state.order : 'asc'}
                onClick={() => this.sortHandler(headCell.title, index)}>
                {headCell.title}
              </TableSortLabel>
            </TableCell>
          ))}
        </TableRow>
      </TableHead>
    );
  }
}

interface IArticle {
  id: number;
  title: string;
  category: string;
  release_date: Date;
  visits: number;
}

interface IFragmentState {
  article: IArticle[];
  // 分页组件
  tablePagination: {
    rowsPerPageOptions: number[];
    count: number;
    rowsPerPage: number;
    page: number;
  };
  alertDialog: IAlertDialog;
  articleOptDialog: {
    open: boolean;
    article: {
      id: number;
      title: string;
    };
  };
}

interface ITitleMap {
  Title: 'title';
  Category: 'category';
  'Release Date': 'release_date';
  Visits: 'visits';
}

const TitleMap: ITitleMap = {
  Title: 'title',
  Category: 'category',
  'Release Date': 'release_date',
  Visits: 'visits',
};

class Fragment extends React.Component<IProps, IFragmentState> {
  constructor(props: IProps) {
    super(props);
    /*
      rowsPerPageOptions={[5, 10, 25]}
      component="div"
      count={rows.length}
      rowsPerPage={rowsPerPage}
      page={page}
    */
    this.handleChangePage = this.handleChangePage.bind(this);
    this.handleChangeRowsPerPage = this.handleChangeRowsPerPage.bind(this);
    this.alertDialogClose = this.alertDialogClose.bind(this);
    this.requestSort = this.requestSort.bind(this);
    this.state = {
      article: [],
      // 分页组件
      tablePagination: {
        rowsPerPageOptions: [],
        count: 0,
        rowsPerPage: 0,
        page: 0,
      },
      alertDialog: {
        msg: '',
        open: false,
      },
      articleOptDialog: {
        open: false,
        article: {
          id: -1,
          title: '',
        },
      },
    };
  }

  componentDidMount() {
    this.getRowsPerPageOptions();
  }

  async getRowsPerPageOptions() {
    const [resErr, config]: any = await adminApi.getConfig({mode: 'json'});
    if (resErr) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: resErr.msg,
          severity: 'error',
        },
      });
    } else {
      const rowsPerPageOptions = config.configData.rowsPerPageOptions;
      this.setState({
        tablePagination: {
          ...this.state.tablePagination,
          rowsPerPageOptions,
          rowsPerPage: rowsPerPageOptions[0],
          page: 0,
        },
      });
      this.getArticlesList(0, rowsPerPageOptions[0]);
    }
  }

  async getArticlesList(page: number, rowsPerPage: number) {
    const [resErr, data]: any = await adminApi.getArticlesList({page, rowsPerPage});
    if (resErr) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: resErr.msg,
          severity: 'error',
        },
      });
    } else {
      const {articleList, count} = data;
      const articleListCopy = articleList.map((item: {visits: number}) => ({...item, visits: Math.random() * 100}));
      this.setState({
        article: articleListCopy,
        tablePagination: {
          ...this.state.tablePagination,
          count,
        },
      });
    }
  }

  alertDialogClose() {
    this.setState({
      alertDialog: {
        ...this.state.alertDialog,
        open: false,
      },
    });
  }

  handleChangePage(event: unknown, page: number) {
    this.setState({
      tablePagination: {
        ...this.state.tablePagination,
        page,
      },
    });

    this.getArticlesList(page, this.state.tablePagination.rowsPerPage);
  }

  handleChangeRowsPerPage(event: React.ChangeEvent<HTMLInputElement>) {
    const rowsPerPage = parseInt(event.target.value, 10);
    this.setState({
      tablePagination: {
        ...this.state.tablePagination,
        rowsPerPage,
      },
    });

    this.getArticlesList(this.state.tablePagination.page, rowsPerPage);
  }

  requestSort(order: 'desc' | 'asc', title: keyof ITitleMap) {
    const sortData = this.state.article.map(item => ({...item}));
    const prop: keyof IArticle = TitleMap[title];
    sortData.sort((a: IArticle, b: IArticle) => {
      return order === 'desc' ? (a[prop] as number) - (b[prop] as number) : (b[prop] as number) - (a[prop] as number);
    });
    this.setState({article: sortData});
  }

  async deleteArticle(id: number) {
    const [errDelete]: any = await trans('deleteArticle', {params: {id}});
    if (errDelete) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: errDelete.msg,
          severity: 'error',
        },
      });
    } else {
      this.setState({articleOptDialog: {...this.state.articleOptDialog, open: false}});
      this.getArticlesList(this.state.tablePagination.page, this.state.tablePagination.rowsPerPage);
    }
  }

  render() {
    return (
      <div className={FragmentWrap}>
        <Paper>
          <TableContainer>
            <Table stickyHeader={true} aria-labelledby="tableTitle" aria-label="enhanced table">
              <TableHeadComponent onRequestSort={this.requestSort} />
              <TableBody>
                {this.state.article.map((row, index) => (
                  <TableRow hover role="checkbox" tabIndex={-1} key={row.id}>
                    <TableCell align="left">{index + 1}</TableCell>
                    <TableCell align="left">{row.title}</TableCell>
                    <TableCell align="left">{row.category}</TableCell>
                    <TableCell align="center">{row['release_date']}</TableCell>
                    <TableCell align="center">{row.visits}</TableCell>
                    <TableCell className={'opts'} align="center">
                      <span className={'btn-view'} onClick={() => this.props.history.push(`/post/${row.id}`)}>
                        View
                      </span>
                      <span className={'btn-edit'} onClick={() => this.props.history.push(`/addblog/${row.id}`)}>
                        Modify
                      </span>
                      <span
                        className={'btn-del'}
                        onClick={() =>
                          this.setState({articleOptDialog: {open: true, article: {title: row.title, id: row.id}}})
                        }>
                        Delete
                      </span>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
          <TablePagination
            rowsPerPageOptions={this.state.tablePagination.rowsPerPageOptions}
            component="div"
            count={this.state.tablePagination.count}
            rowsPerPage={this.state.tablePagination.rowsPerPage}
            page={this.state.tablePagination.page}
            onChangePage={this.handleChangePage}
            onChangeRowsPerPage={this.handleChangeRowsPerPage}
          />
        </Paper>
        <AlertDialog {...this.state.alertDialog} onClose={this.alertDialogClose} />
        <Dialog
          onClose={() => this.setState({articleOptDialog: {...this.state.articleOptDialog, open: false}})}
          aria-labelledby="customized-dialog-title"
          open={this.state.articleOptDialog.open}>
          <DialogTitle id="customized-dialog-title">删除文章</DialogTitle>
          <DialogContent dividers>
            <Typography gutterBottom>确定删除文章: {this.state.articleOptDialog.article.title}</Typography>
          </DialogContent>
          <DialogActions>
            <Button
              autoFocus
              onClick={() => this.setState({articleOptDialog: {...this.state.articleOptDialog, open: false}})}
              color="primary">
              取消
            </Button>
            <Button
              autoFocus
              onClick={() => this.deleteArticle(this.state.articleOptDialog.article.id)}
              color="primary">
              确定
            </Button>
          </DialogActions>
        </Dialog>
      </div>
    );
  }
}

export default Fragment;
